package Underworld_Survival;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class EffectManager implements Serializable {
    // 存储效果记录 <效果ID, 效果记录>
    private final Map<String, EffectRecord> activeEffect = new HashMap<>();
    // 存储来源与效果的映射 <来源ID, 关联效果ID集合>
    private final Map<String, Set<String>> sourceMapping = new HashMap<>();


//    数据结构
//    activeEffect: {
//        "E1": {source:"剑#001", modifications:{STR:+5} },
//        "E2": {source:"斧#002", modifications:{STR:+3, CRIT:+0.1} }
//    }
//    sourceMapping: {
//        "剑#001": ["E1"],
//        "斧#002": ["E2"]
//    }

    /**
     * 注册效果并返回唯一ID
     * @param sourceId 效果来源标识（如装备UUID）
     * @param effects 效果集合
     * @return 生成的效果ID
     */
    public String applyEffect(String sourceId, Map<AttributeType, EffectValue> effects) {
        String effectId = UUID.randomUUID().toString()+"效果唯一标识";
        EffectRecord record = new EffectRecord(sourceId, effects);

        activeEffect.put(effectId, record);
        sourceMapping.computeIfAbsent(sourceId, k -> new HashSet<>()).add(effectId);
        return effectId;
    }

    //根据效果id获取属性加成
    public Map<AttributeType, Float> getEffectsById(String effectId, Role context) {
        EffectRecord record = activeEffect.get(effectId);
        if (record == null) return Collections.emptyMap();
        return record.resolveValues(context);
    }

    //根据来源获取应该加的属性加成
    public Map<AttributeType, Float> getEffectsBySource(String sourceId, Role context) {
        Map<AttributeType, Float> totals = new HashMap<>();
        // 通过来源ID获取关联的所有效果ID
        Set<String> effectIds = sourceMapping.getOrDefault(sourceId, Collections.emptySet());
        effectIds.stream()
                .map(activeEffect::get)      // 获取每个效果记录
                .filter(Objects::nonNull)    // 过滤无效记录
                .forEach(record ->
                        record.resolveValues(context).forEach((type, value) ->
                                totals.merge(type, value, Float::sum)
                        )
                );
        return totals;
    }

    /**
     * 移除指定来源的所有效果
     * @param sourceId 效果来源标识
     * @return 需要反向操作的数值集合
     */
    public Map<AttributeType, Float> removeEffects(String sourceId,Role role) {
        Set<String> effectIds = sourceMapping.remove(sourceId);
        if (effectIds == null) return Collections.emptyMap();

        Map<AttributeType, Float> totalReverse = new HashMap<>();
        effectIds.forEach(id -> {
            EffectRecord record = activeEffect.remove(id);
            record.resolveValues(role).forEach((type, value) ->
                    totalReverse.merge(type, -value, Float::sum)
            );
        });
        return totalReverse;
    }


    // 增强版全效果清除
    public void purgeAllEffects(Player player) {
        // 阶段1：收集所有需要处理的效果源
        Set<String> allSources = new ConcurrentHashMap<>(sourceMapping).keySet();
        Map<AttributeType, Float> totalReversion = new HashMap<>();

        // 阶段2：批量处理已知来源效果
        allSources.forEach(sourceId -> {
            Map<AttributeType, Float> partial = this.removeEffects(sourceId,player);
            partial.forEach((k, v) -> totalReversion.merge(k, v, Float::sum));
        });

        // 阶段3：处理游离效果（无来源登记的效果）
        new HashMap<>(activeEffect).keySet().forEach(effectId -> {
            EffectRecord record = activeEffect.remove(effectId);
            record.resolveValues(player).forEach((attr, value) ->
                    totalReversion.merge(attr, -value, Float::sum)
            );
        });

        // 阶段4：应用总反向修正
        applyTotalReversion(player, totalReversion);

        // 阶段5：最终状态验证
        validateCleanState();
    }

    private void applyTotalReversion(Player player, Map<AttributeType, Float> reversions) {
        player.modifyAttributes(reversions,false);
        // 更新派生属性（如总攻击力=基础力量+装备加成）
        player.updateAttribute();
    }

    private void validateCleanState() {
        if (!activeEffect.isEmpty() || !sourceMapping.isEmpty()) {
            throw new IllegalStateException("效果清除未完成！残留效果: "
                    + activeEffect.keySet()+activeEffect.values()+sourceMapping.keySet());
        }
    }

    // 新增状态检查方法
    public boolean isPlayerClean(Player player) {
        return activeEffect.isEmpty()
                && sourceMapping.isEmpty()
                && player.getEffectManager().getActiveEffect().isEmpty();
    }


    // 效果值转换逻辑
    private GameSaveData.EffectManagerArchive.EffectValueData convertEffectValue(EffectValue value) {
        if (value instanceof FixedValue) {
            return new GameSaveData.EffectManagerArchive.EffectValueData(
                    "fixed",
                    Map.of("value", ((FixedValue)value).value())
            );
        } else if (value instanceof DynamicValue) {
            // 动态效果需要特殊处理（示例使用公式字符串）
            return new GameSaveData.EffectManagerArchive.EffectValueData(
                    "dynamic",
                    Map.of("formula", "STR*0.2") // 实际项目应序列化计算逻辑
            );
        }
        throw new IllegalArgumentException("未知效果值类型");
    }

    public GameSaveData.EffectManagerArchive toArchive() {
        GameSaveData.EffectManagerArchive data = new GameSaveData.EffectManagerArchive();

        // 转换效果记录
        this.activeEffect.forEach((effectId, record) -> {
            Map<AttributeType, GameSaveData.EffectManagerArchive.EffectValueData> mods = new HashMap<>();

            record.modifications.forEach((attrType, effectValue) -> {
                mods.put(attrType, convertEffectValue(effectValue));
            });

            data.effectRecords.put(effectId,
                    new GameSaveData.EffectManagerArchive.EffectRecordData(
                            record.getSourceId(),
                            mods
                    ));
        });

        // 转换来源映射
        data.sourceMapping.putAll(this.sourceMapping);

        return data;
    }


    // 在EffectManager中添加加载方法
    public void loadFromArchive(GameSaveData.EffectManagerArchive data) {
        this.activeEffect.clear();
        this.sourceMapping.clear();

        // 重建效果记录
        data.effectRecords.forEach((effectId, recordData) -> {
            Map<AttributeType, EffectValue> mods = new HashMap<>();

            recordData.modifications.forEach((attrType, valueData) -> {
                mods.put(attrType,
                        GameRegistry.EffectValueRegistry.create(
                                valueData.typeId,
                                valueData.params
                        ));
            });

            this.activeEffect.put(effectId,
                    new EffectRecord(recordData.sourceId, mods));
        });

        // 重建来源映射
        this.sourceMapping.putAll(data.sourceMapping);
    }





    public Map<AttributeType, Float> getCurrentEffects(Role context) {
        Map<AttributeType, Float> totals = new HashMap<>();
        activeEffect.values().forEach(record ->
                record.resolveValues(context).forEach((type, value) ->
                        totals.merge(type, value, Float::sum)
                )
        );
        return totals;
    }

    public EffectRecord getEffectById(String effectId) {return activeEffect.get(effectId);}



    //效果记录器所有效果记录的输出
    // 增强版效果输出方法
    public String printEffects(Role context) {
        StringBuilder sb = new StringBuilder("=== 当前生效效果 ===");

        // 按来源分组显示
        sourceMapping.forEach((sourceId, effectIds) -> {
            sb.append("\n\n【来源: ").append(sourceId).append("】");
            effectIds.forEach(effectId -> appendEffect(sb, effectId, context));
        });

        // 显示游离效果
        activeEffect.keySet().stream()
                .filter(effectId -> sourceMapping.values().stream()
                        .noneMatch(set -> set.contains(effectId)))
                .forEach(effectId -> {
                    sb.append("\n\n【游离效果】");
                    appendEffect(sb, effectId, context);
                });

        return sb.toString();
    }

    private void appendEffect(StringBuilder sb, String effectId, Role context) {
        EffectRecord record = activeEffect.get(effectId);
        if (record == null) return;

        sb.append("\n◇ 效果ID: ").append(effectId)
                .append("\n   来源标识: ").append(record.getSourceId())
                .append("\n   属性修正:");

        record.getModifications().forEach((attr, effectValue) -> {
            String valueDisplay = formatValue(effectValue, context);
            sb.append("\n   ▷ ").append(attr.name()).append(": ").append(valueDisplay);
        });

//        // 显示持续时间（如果有）
//        if (record.getDuration() > 0) {
//            sb.append("\n   持续时间: ")
//                    .append(record.getRemainingDuration())
//                    .append("/")
//                    .append(record.getInitialDuration());
//        }
    }

    private String formatValue(EffectValue effectValue, Role context) {
        try {
            float value = effectValue.getValue(context);
            if (effectValue instanceof FixedValue) {
                return String.format("%+.2f (固定)", value);
            } else if (effectValue instanceof DynamicValue) {
                return String.format("%+.2f (动态)", value);
            }
            return String.format("%+.1f", value);
        } catch (NullPointerException e) {
            return "[需上下文计算]";
        }
    }

    public Map<String, EffectRecord> getActiveEffect(){
        return activeEffect;
    }

}
